#include "Shape2D.h"

Circle::Circle(real radius) : radius(radius)
{
}

real Circle::getRadius() const
{
    return radius;
}

void Circle::setRadius(real radius)
{
    this->radius = radius;
}

Rectangle::Rectangle(const Vector2 &size) : size(size)
{
}

Vector2 Rectangle::getSize() const
{
    return size;
}

void Rectangle::setSize(const Vector2 &size)
{
    this->size = size;
}

Triangle::Triangle(Vector2 p1, Vector2 p2, Vector2 p3)
{
    p[0] = p1;
    p[1] = p2;
    p[2] = p3;

    Vector2 dt1 = (p[1] - p[0]).normalized();
    Vector2 dt2 = (p[2] - p[0]).normalized();
    // Log::log("dt1:%f dt2:%f\n", dt1, dt2);
    assert(dt1 != dt2 && dt1 != -dt2);

    // 最左边点
    int index = 0;
    int min = p1.x;
    for (int i = 1; i < 3; ++i)
    {
        if (p[i].x < min)
        {
            min = p[i].x;
            index = i;
        }
    };
    Vector2 temp = p[0];
    p[0] = p[index];
    p[index] = temp;
    // 两点上边点
    if (p[1].y > p[2].y)
    {
        temp = p[1];
        p[1] = p[2];
        p[2] = temp;
    }

    real x1 = p[0].x;
    real y1 = p[0].y;
    real x2 = p[1].x;
    real y2 = p[1].y;
    real x3 = p[2].x;
    real y3 = p[2].y;

    real a = ((y2 - y1) * (y3 * y3 - y1 * y1 + x3 * x3 - x1 * x1) - (y3 - y1) * (y2 * y2 - y1 * y1 + x2 * x2 - x1 * x1)) / (2.0 * ((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1)));
    real b = ((x2 - x1) * (x3 * x3 - x1 * x1 + y3 * y3 - y1 * y1) - (x3 - x1) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1)) / (2.0 * ((y3 - y1) * (x2 - x1) - (y2 - y1) * (x3 - x1)));
    real r = (x1 - a) * (x1 - a) + (y1 - b) * (y1 - b);

    circleCenter = Vector2(a, b);
    this->r2 = r;
    center = Vector2();
    for (int i = 0; i < 3; ++i)
    {
        center += p[i];
    }
    center /= 3;
}

const Vector2 *Triangle::getPoints() const
{
    return p;
}

Vector2 Triangle::getCircleCenter() const
{
    return circleCenter;
}

Vector2 Triangle::getCenter() const
{
    return center;
}

real Triangle::getRadius2() const
{
    return r2;
}

Polygon::Polygon(Vector2 *ps, int size)
{
    for (int i = 0; i < size; ++i)
    {
        plist.push_back(ps[i]);
    }
}

const std::vector<Vector2> Polygon::getPoints() const
{
    return plist;
}
